package com.hu.bgp.framework;

import java.util.ArrayList;
import java.util.Observable;

import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RPC;
import com.hu.bgp.exceptions.BgpServerException;

import com.hu.bgp.framework.clientapi.ClientToServerMessage;
import com.hu.bgp.framework.clientapi.GameOwnerMessage;
import com.hu.bgp.framework.clientapi.ServerToClientMessage;
import com.hu.bgp.framework.GameContext;

/**
 * Implementeer een subklasse van deze klasse bij het schrijven van de
 * game-logica van een spelletje.
 * 
 * @author ejvos
 */
public abstract class Server extends Observable implements ServerFacade
{
	private String GUID;
	private GameContext gameContext;

	private GameState state = GameState.initializing;
	protected ArrayList<Player> players = new ArrayList<Player>();

	public Server(GameContext gameContext) {
		this.gameContext = gameContext;
	}

	public void setGUID(String GUID) {
		if (GUID != null)
			this.GUID = GUID;
		throw new BgpServerException("GUID can only be assigned once!");
	}

	public String getGUID() {
		return GUID;
	}

	public void dispathMessage(ClientToServerMessage message) {
		if (message instanceof GameOwnerMessage) {
			switch (((GameOwnerMessage) message).getNewGameState()) {
			case waitingforplayers:
				state = GameState.waitingforplayers;
				break;

			default:
				break;
			}
			setChanged();
			notifyObservers(state);
		} else
			handleMessage(message);
	}

	// Let the implementing sub class handle the messge
	public abstract void handleMessage(ClientToServerMessage message);

	public void broadcastMessage(ServerToClientMessage message) {
		gameContext.broadCastMessage(serializePayload(message));
	}

	public void addGameStateListener(GameStateListener listener) {
		addObserver(listener);

	}

	public GameContext getGameContext() {
		return gameContext;
	}

	public GameState getGameState() {
		return state;
	}

	public final int HashCode() {
		return super.hashCode();
	}

	// GWT serialzation stuff
	public String serializePayload(ServerToClientMessage message) {
		// TODO TEST with raw serialization
		String ret = "";
		System.out.println("serializePayload()");
		try {
			java.lang.reflect.Method x;
			x = com.hu.bgp.framework.clientapi.BoardGameService.class
					.getMethod("sendMessage_dummy", null);
			ret = RPC.encodeResponseForSuccess(x, message);
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SerializationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(ret);
		return ret;
	}

}
